home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src.arc / MAIN.C < prev    next >
C/C++ Source or Header  |  1989-08-19  |  11KB  |  577 lines

  1. /* Main network program - provides both client and server functions */
  2. #define HOSTNAMELEN 32        /* changed from 16 by Bdale 860812 */
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include <io.h>
  6. #ifdef    ANSIPROTO
  7. #include <stdarg.h>
  8. #endif
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "socket.h"
  12. #include "iface.h"
  13. #include "ftpcli.h"
  14. #include "telnet.h"
  15. #include "ax25tnc.h"
  16. #include "remote.h"
  17. #include "session.h"
  18. #include "cmdparse.h"
  19. #include "ax25.h"
  20. #include "kiss.h"
  21. #include "enet.h"
  22. #include "timer.h"
  23. #include "proc.h"
  24. #include "tty.h"
  25. #include "daemon.h"
  26. #include "usock.h"
  27. #include "netrom.h"
  28. #include "ip.h"
  29. #include "tcp.h"
  30. #include "udp.h"
  31. #include "pc.h"
  32. #include "commands.h"
  33.  
  34. extern struct cmds Cmds[],Startcmds[],Stopcmds[];
  35. extern int32 Heapsize;
  36. extern struct daemon Daemons[];
  37. extern char Version[];
  38. extern char *Startup;    /* File to read startup commands from */
  39. extern int Refuse_echo;
  40. extern int Unix_line_mode;
  41. extern char *Rempass;
  42.  
  43. #ifndef    MSDOS            /* PC uses F-10 key always */
  44. static char Escape = 0x1d;    /* default escape character is ^] */
  45. #endif
  46.  
  47. char Badhost[] = "Unknown host %s\n";
  48. char Hostname[HOSTNAMELEN];    
  49. static char Prompt[] = "net> ";
  50. char Nospace[] = "No space!!\n";    /* Generic malloc fail message */
  51. struct mbuf *Hopper;
  52. static FILE *Logfp;
  53. static struct mbuf *Cmdq;
  54. static struct proc *Cmdpp;
  55. extern struct cmds Attab[];
  56.  
  57. int
  58. main(argc,argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.     char *inbuf,*intmp;
  63.     FILE *fp;
  64.     struct daemon *tp;
  65.     struct mbuf *bp;
  66.     int c;
  67.     extern char *optarg;
  68.     extern int optind;
  69.  
  70.     while((c = getopt(argc,argv,"s:d:m:")) != EOF){
  71.         switch(c){
  72.         case 's':    /* Number of sockets */
  73.             Nusock = atoi(optarg);
  74.             break;
  75.         case 'd':    /* Root directory for various files */
  76.             initroot(optarg);
  77.             break;
  78.         case 'm':    /* Heap memory size */
  79.             Heapsize = 1024 * atol(optarg);
  80.             break;
  81.         }
  82.     }
  83.     kinit();
  84.     ioinit(Heapsize);
  85.     sockinit();
  86.     Cmdpp = mainproc("cmdintrp");
  87.     ttysetmode(TTY_ECHO|TTY_EDIT);
  88.     printf("KA9Q Internet Protocol Package, v%s\n",Version);
  89.     printf("Copyright 1989 by Phil Karn, KA9Q\n");
  90.     fflush(stdout);
  91.     Sessions = (struct session *)calloc(Nsessions,sizeof(struct session));
  92.  
  93.     if(optind < argc){
  94.         /* Read startup file named on command line */
  95.         if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
  96.             printf("Can't read config file %s: %s\n",
  97.              argv[optind],sys_errlist[errno]);
  98.     } else {
  99.         fp = fopen(Startup,READ_TEXT);
  100.     }
  101.     if(fp != NULLFILE){
  102.         inbuf = malloc(BUFSIZ);
  103.         intmp = malloc(BUFSIZ);
  104.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  105.             strcpy(intmp,inbuf);
  106.             if(cmdparse(Cmds,inbuf,NULL) != 0){
  107.                 printf("input line: %s",intmp);
  108.             }
  109.         }
  110.         fclose(fp);
  111.         free(inbuf);
  112.         free(intmp);
  113.     }
  114.     /* Start background Daemons */
  115.     for(tp=Daemons;;tp++){
  116.         if(tp->name == NULLCHAR)
  117.             break;
  118.         newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL);
  119.     }
  120.     /* Now loop forever, processing commands */
  121.     for(;;){
  122.         printf(Prompt);
  123.         while(Cmdq == NULLBUF)
  124.             pwait(&Cmdq);
  125.         bp = dequeue(&Cmdq);
  126.         (void)cmdparse(Cmds,bp->data,Current);
  127.         free_p(bp);
  128.         ttysetmode(TTY_ECHO|TTY_EDIT);
  129.     }
  130. }
  131. /* Keyboard input process */
  132. void
  133. keyboard(i,v1,v2)
  134. int i;
  135. void *v1;
  136. void *v2;
  137. {
  138.     int c;
  139.     struct mbuf *bp;
  140.  
  141.     /* Keyboard process loop */
  142.     for(;;){
  143.         c = kbread();
  144. #ifndef    MSDOS
  145.         if(c == Escape && Escape != 0)
  146.             c = -2;
  147. #endif
  148.         /* c == -2 means the command escape key */
  149.         if(c == -2){
  150.             /* Save current tty mode and set cooked */
  151.             if(Current != NULLSESSION && Mode == CONV_MODE){
  152.                 Current->ttymode = ttygetmode();
  153.                 Mode = CMD_MODE;
  154.                 ttysetmode(TTY_ECHO|TTY_EDIT);
  155.                 printf("\n");
  156.                 /* Wake up the command interpreter */
  157.                 alert(Cmdpp,0);
  158.             }
  159.         /* Else give to line editor; if done, queue it */
  160.         } else if((bp = ttydriv(c)) != NULLBUF){
  161.             switch(Mode){
  162.             case CMD_MODE:
  163.                 enqueue(&Cmdq,bp);
  164.                 break;
  165.             case CONV_MODE:
  166.                 enqueue(&Current->input,bp);
  167.                 break;
  168.             }
  169.         }
  170.     }
  171. }
  172. /* Standard commands called from main */
  173. int
  174. dodelete(argc,argv,p)
  175. int argc;
  176. char *argv[];
  177. void *p;
  178. {
  179.     int i;
  180.  
  181.     for(i=1;i < argc; i++){
  182.         if(unlink(argv[i]) == -1){
  183.             printf("Can't delete %s: %s\n",
  184.              argv[i],sys_errlist[errno]);
  185.         }
  186.     }
  187.     return 0;
  188. }
  189. int
  190. dorename(argc,argv,p)
  191. int argc;
  192. char *argv[];
  193. void *p;
  194. {
  195.     if(rename(argv[1],argv[2]) == -1)
  196.         printf("Can't rename: %s\n",sys_errlist[errno]);
  197.     return 0;
  198. }
  199. int
  200. doexit(argc,argv,p)
  201. int argc;
  202. char *argv[];
  203. void *p;
  204. {
  205.     reset_all();
  206.     iostop();
  207.     exit(0);
  208.     return 0;    /* To satisfy lint */
  209. }
  210. int
  211. dohostname(argc,argv,p)
  212. int argc;
  213. char *argv[];
  214. void *p;
  215. {
  216.     if(argc < 2)
  217.         printf("%s\n",Hostname);
  218.     else 
  219.         strncpy(Hostname,argv[1],HOSTNAMELEN);
  220.     return 0;
  221. }
  222. int
  223. dolog(argc,argv,p)
  224. int argc;
  225. char *argv[];
  226. void *p;
  227. {
  228.     static char logname[15];
  229.  
  230.     if(argc < 2){
  231.         if(Logfp)
  232.             printf("Logging to %s\n",logname);
  233.         else
  234.             printf("Logging off\n");
  235.         return 0;
  236.     }
  237.     if(Logfp){
  238.         fclose(Logfp);
  239.         Logfp = NULLFILE;
  240.     }
  241.     if(strcmp(argv[1],"stop") != 0){
  242.         strncpy(logname,argv[1],15);
  243.         Logfp = fopen(logname,APPEND_TEXT);
  244.     }
  245.     return 0;
  246. }
  247. int
  248. dohelp(argc,argv,p)
  249. int argc;
  250. char *argv[];
  251. void *p;
  252. {
  253.     register struct cmds *cmdp;
  254.     int i,j;
  255.  
  256.     printf("Main commands:\n");
  257.     for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i++){
  258.         printf("%s",cmdp->name);
  259.         if((i % 4) == 3)
  260.             printf("\n");
  261.         else {
  262.             for(j=strlen(cmdp->name);j < 16; j++)
  263.                 putchar(' ');
  264.         }
  265.     }
  266.     if((i % 4) != 0)
  267.         printf("\n");
  268.     return 0;
  269. }
  270. int
  271. doecho(argc,argv,p)
  272. int argc;
  273. char *argv[];
  274. void *p;
  275. {
  276.     if(argc < 2){
  277.         if(Refuse_echo)
  278.             printf("Refuse\n");
  279.         else
  280.             printf("Accept\n");
  281.     } else {
  282.         if(argv[1][0] == 'r')
  283.             Refuse_echo = 1;
  284.         else if(argv[1][0] == 'a')
  285.             Refuse_echo = 0;
  286.         else
  287.             return -1;
  288.     }
  289.     return 0;
  290. }
  291. /* set for unix end of line for remote echo mode telnet */
  292. int
  293. doeol(argc,argv,p)
  294. int argc;
  295. char *argv[];
  296. void *p;
  297. {
  298.     if(argc < 2){
  299.         if(Unix_line_mode)
  300.             printf("Unix\n");
  301.         else
  302.             printf("Standard\n");
  303.     } else {
  304.         if(strcmp(argv[1],"unix") == 0)
  305.             Unix_line_mode = 1;
  306.         else if(strcmp(argv[1],"standard") == 0)
  307.             Unix_line_mode = 0;
  308.         else {
  309.             return -1;
  310.         }
  311.     }
  312.     return 0;
  313. }
  314. /* Attach an interface
  315.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  316.  */
  317. int
  318. doattach(argc,argv,p)
  319. int argc;
  320. char *argv[];
  321. void *p;
  322. {
  323.     return subcmd(Attab,argc,argv,p);
  324. }
  325. /* Manipulate I/O device parameters */
  326. int
  327. doparam(argc,argv,p)
  328. int argc;
  329. char *argv[];
  330. void *p;
  331. {
  332.     register struct iface *ifp;
  333.  
  334.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  335.         if(strcmp(argv[1],ifp->name) == 0)
  336.             break;
  337.     }
  338.     if(ifp == NULLIF){
  339.         printf("Interface \"%s\" unknown\n",argv[1]);
  340.         return 1;
  341.     }
  342.     if(ifp->ioctl == NULLFP){
  343.         printf("Not supported\n");
  344.         return 1;
  345.     }
  346.     /* Pass rest of args to device-specific code */
  347.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  348. }
  349.  
  350. /* Display or set IP interface control flags */
  351. int
  352. domode(argc,argv,p)
  353. int argc;
  354. char *argv[];
  355. void *p;
  356. {
  357.     register struct iface *ifp;
  358.  
  359.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  360.         if(strcmp(argv[1],ifp->name) == 0)
  361.             break;
  362.     }
  363.     if(ifp == NULLIF){
  364.         printf("Interface \"%s\" unknown\n",argv[1]);
  365.         return 1;
  366.     }
  367.     if(argc < 3){
  368.         printf("%s: %s\n",ifp->name,
  369.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  370.         return 0;
  371.     }
  372.     switch(argv[2][0]){
  373.     case 'v':
  374.     case 'c':
  375.     case 'V':
  376.     case 'C':
  377.         ifp->flags = CONNECT_MODE;
  378.         break;
  379.     case 'd':
  380.     case 'D':
  381.         ifp->flags = DATAGRAM_MODE;
  382.         break;
  383.     default:
  384.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  385.         return 1;
  386.     }
  387.     return 0;
  388. }
  389.  
  390. #ifndef    MSDOS
  391. static int
  392. doescape(argc,argv,p)
  393. int argc;
  394. char *argv[];
  395. void *p;
  396. {
  397.     if(argc < 2)
  398.         printf("0x%x\n",Escape);
  399.     else 
  400.         Escape = *argv[1];
  401.     return 0;
  402. }
  403. #endif    MSDOS
  404. /* Generate system command packet. Synopsis:
  405.  * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
  406.  */
  407. int
  408. doremote(argc,argv,p)
  409. int argc;
  410. char *argv[];
  411. void *p;
  412. {
  413.     struct sockaddr_in fsock;
  414.     int s,c;
  415.     char *data,x;
  416.     extern int errno;
  417.     extern char *optarg;
  418.     extern int optind;
  419.     int16 port,len;
  420.     char *key = NULLCHAR;
  421.     int klen;
  422.     int32 addr = 0;
  423.     char *cmd,*host;
  424.  
  425.     port = IPPORT_REMOTE;    /* Set default */
  426.     optind = 1;        /* reinit getopt() */
  427.     while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
  428.         switch(c){
  429.         case 'a':
  430.             addr = resolve(optarg);
  431.             break;
  432.         case 'p':
  433.             port = atoi(optarg);
  434.             break;
  435.         case 'k':
  436.             key = optarg;
  437.             klen = strlen(key);
  438.             break;
  439.         case 's':
  440.             Rempass = strdup(optarg);
  441.             return 0;    /* Only set local password */
  442.         }
  443.     }
  444.     if(optind > argc - 2){
  445.         printf("Insufficient args\n");
  446.         return -1;
  447.     }
  448.     host = argv[optind++];
  449.     cmd = argv[optind];
  450.     if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  451.         printf("socket failed\n");
  452.         return 1;
  453.     }
  454.     len = 1;
  455.     /* Did the user include a password or kickme target? */
  456.     if(addr != 0)
  457.         len += sizeof(int32);
  458.  
  459.     if(key != NULLCHAR)
  460.         len += klen;
  461.  
  462.     if(len == 1)
  463.         data = &x;
  464.     else
  465.         data = malloc(len);
  466.  
  467.     fsock.sin_family = AF_INET;
  468.     fsock.sin_addr.s_addr = resolve(host);
  469.     fsock.sin_port = port;
  470.  
  471.     switch(cmd[0]){
  472.     case 'r':
  473.         data[0] = SYS_RESET;
  474.         if(key != NULLCHAR)
  475.             strncpy(&data[1],key,klen);
  476.         break;
  477.     case 'e':
  478.         data[0] = SYS_EXIT;
  479.         if(key != NULLCHAR)
  480.             strncpy(&data[1],key,klen);
  481.         break;
  482.     case 'k':
  483.         data[0] = KICK_ME;
  484.         if(addr != 0)
  485.             put32(&data[1],addr);
  486.         break;
  487.     default:
  488.         printf("Unknown command %s\n",cmd);
  489.         goto cleanup;
  490.     }
  491.     /* Form the command packet and send it */
  492.     if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
  493.         printf("sendto failed: %s\n",sys_errlist[errno]);
  494.         goto cleanup;
  495.     }
  496. cleanup:
  497.     if(data != &x)
  498.         free(data);
  499.     close_s(s);
  500.     return 0;
  501. }
  502.  
  503. /* Log messages of the form
  504.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  505.  */
  506. #ifdef    ANSIPROTO
  507. void
  508. log(int s,char *fmt, ...)
  509. {
  510.     va_list ap;
  511.     char *cp;
  512.     long t;
  513.     int fd,i;
  514.     struct sockaddr fsocket;
  515.  
  516.     if(Logfp == NULLFILE)
  517.         return;
  518.  
  519.     time(&t);
  520.     cp = ctime(&t);
  521.     rip(cp);
  522.     i = SOCKSIZE;
  523.     fprintf(Logfp,"%s",cp);
  524.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  525.         fprintf(Logfp," %s",psocket(&fsocket));
  526.  
  527.     fprintf(Logfp," - ");
  528.     va_start(ap,fmt);
  529.     vfprintf(Logfp,fmt,ap);
  530.     va_end(ap);
  531.     fprintf(Logfp,"\n");
  532.     fflush(Logfp);
  533. #ifdef    MSDOS
  534.     /* MS-DOS doesn't really flush files until they're closed */
  535.     fd = fileno(Logfp);
  536.     if((fd = dup(fd)) != -1)
  537.         close(fd);
  538. #endif
  539.  
  540. }
  541. #else
  542. /*VARARGS2*/
  543. void
  544. log(s,fmt,arg1,arg2,arg3,arg4,arg5)
  545. int s;
  546. char *fmt;
  547. int arg1,arg2,arg3,arg4,arg5;
  548. {
  549.     char *cp;
  550.     long t;
  551.     int fd,i;
  552.     struct sockaddr fsocket;
  553.  
  554.     if(Logfp == NULLFILE)
  555.         return;
  556.     time(&t);
  557.     cp = ctime(&t);
  558.     rip(cp);
  559.     i = SOCKSIZE;
  560.     fprintf(Logfp,"%s",cp);
  561.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  562.         fprintf(Logfp," %s",psocket(&fsocket));
  563.  
  564.     fprintf(Logfp," - ");
  565.     fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
  566.     fprintf(Logfp,"\n");
  567.     fflush(Logfp);
  568. #ifdef    MSDOS
  569.     /* MS-DOS doesn't really flush files until they're closed */
  570.     fd = fileno(Logfp);
  571.     if((fd = dup(fd)) != -1)
  572.         close(fd);
  573. #endif
  574. }
  575. #endif
  576.  
  577.